package com.bbz.core.queue;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 非阻塞队列 ConcurrentLinkedQueue 是基于链接节点的、线程安全的队列。并发访问不需要同步。
 * 因为它在队列的尾部添加元素并从头部删除它们，所以只要不需要知道队列的大 小， ConcurrentLinkedQueue
 * 对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息会很慢，需要遍历队列。
 * 
 * @author binbin.a.zhang
 *
 */
public class ConcurrentLinkedQueueDemo {
	/**
	 * 定义装苹果的篮子
	 */
	public static class Basket {
		// 篮子，能够容纳3个苹果
		ConcurrentLinkedQueue<String> basket = new ConcurrentLinkedQueue<String>();

		// 生产苹果，放入篮子
		public void produce(String Topic,int i) throws InterruptedException {
			// put方法放入一个苹果，若basket满了，等到basket有位置
			basket.add(Topic + i);
			System.out.println("生产者生产"+Topic+"完毕：" + Topic + i);
		}

		// 消费苹果，从篮子中取走
		public String consume() throws InterruptedException {
			// get方法取出一个苹果，若basket为空，等到basket有苹果为止
			String apple = basket.poll();
			return apple;
		}

		public int getAppleNumber() {
			return basket.size();
		}

	}

	// 测试方法
	public static void testBasket() {
		// 建立一个装苹果的篮子
		final Basket basket = new Basket();
		// 定义苹果生产者
		class Producer implements Runnable {
			int i = 0;
			String name;
			String Topic;

			public Producer(String name,String Topic) {
				this.name = name;
				this.Topic = Topic;
			}

			public void run() {
				try {
					while (true) {
						i++;
						// 生产苹果
						basket.produce(Topic,i);
						System.out.println(name + "生产完后有苹果：" + basket.getAppleNumber() + "个");
						// 休眠300ms
						Thread.sleep(300);
					}
				} catch (InterruptedException ex) {
				}
			}
		}
		// 定义苹果消费者
		class Consumer implements Runnable {
			String name;

			public Consumer(String name) {
				this.name = name;
			}

			public void run() {
				try {
					while (true) {
						// 消费苹果
						String apple = basket.consume();
						System.out.println("消费者" + name + "消费苹果：" + apple);
						System.out.println("消费完后有苹果：" + basket.getAppleNumber() + "个");
						// 休眠1000ms
						Thread.sleep(1000);
					}
				} catch (InterruptedException ex) {
				}
			}
		}

		ExecutorService service = Executors.newCachedThreadPool();
		Producer producer = new Producer("AAAAAA","苹果");
		Consumer consumer = new Consumer("小王");
		Consumer consumer1 = new Consumer("小李");
		Consumer consumer2 = new Consumer("小張");
		service.submit(producer);
		service.submit(consumer);
		service.submit(consumer1);
		service.submit(consumer2);
		// 程序运行10s后，所有任务停止
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
		}
		service.shutdownNow();
	}

	public static void main(String[] args) {
		ConcurrentLinkedQueueDemo.testBasket();
	}

}
